import os
from abc import ABC, abstractmethod
from dataclasses import dataclass
from logging import WARNING
from pathlib import Path
from typing import Optional, Union, List

from enumerate.unzip_enum import OtherTool
from utils.LogDecorator import LogDecorator


@dataclass
class ToolConfig:
    password: Optional[str] = None
    input_path: Optional[Union[str, Path]] = None
    output_path: Optional[Union[str, Path]] = None
    compression_type: Optional[str] = "7z"
    volume: Optional[str] = None


class BaseTool(ABC):
    """工具基类，提供配置管理"""

    log = LogDecorator(name=__name__, level=WARNING)

    def __init__(self):
        self._config = ToolConfig()

    @property
    def config(self) -> ToolConfig:
        """获取配置对象(只读)"""
        return self._config

    def set_password(self, password: str) -> 'BaseTool':
        """设置密码"""
        self._config.password = password
        return self

    def set_input_path(self, input_path: str) -> 'BaseTool':
        """设置输入路径"""
        if not os.path.exists(input_path):
            raise FileNotFoundError(f"文件不存在: {input_path}")
        self._config.input_path = input_path
        return self

    def set_output_path(self, output_path: str) -> 'BaseTool':
        """设置输出路径"""
        self._config.output_path = output_path
        return self

    @abstractmethod
    def build_command(self) -> List[str]:
        """构建命令(子类必须实现)"""
        pass

    def __str__(self) -> str:
        """获取工具名称"""
        return self.__class__.__name__


class CompressionTool(BaseTool, ABC):
    """压缩工具基类"""

    def set_compression_type(self, compression_type: str) -> 'CompressionTool':
        """设置压缩类型"""
        self._config.compression_type = compression_type
        return self

    def set_volume(self, volume: int) -> 'CompressionTool':
        """设置分卷大小(MB)"""
        if volume <= 0:
            raise ValueError("分卷大小必须大于0")
        self._config.volume = OtherTool.format_size(volume, self.__class__.__name__)
        return self


class DecompressionTool(BaseTool, ABC):
    """解压工具基类"""
    pass
